import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;

/**
 * trieda zapisujuca vystupne subory
 * @author erik, cerko
 *
 */
public class OutputManager {
	
	private File texOutuput;
	private File bibTexOutput;
	private File format;
	private Map<String, Data> usedRefs;
	private OutputFormatter formatter;
	private BufferedWriter bufferedWriter;
	private String lineBreak;
	
	/**
	 * konstruktor pre 3. cast na zapis do bibtexu
	 * @param bibTexOutput
	 * @param usedRefs
	 */
	public OutputManager(File bibTexOutput, Map<String, Data> usedRefs){
		this.texOutuput = bibTexOutput;
		this.usedRefs = usedRefs;
		this.bibTexOutput = bibTexOutput;
		lineBreak = System.getProperty("line.separator");
		
	}
	
	/**
	 * konstruktor pre 1. a 2. cast pre zapis do texu
	 * @param texOutput
	 * @param format
	 * @param usedRefs
	 */
	public OutputManager(File texOutput, File format, Map<String, Data> usedRefs){
		this.texOutuput = texOutput;
		this.format = format;
		this.usedRefs = usedRefs;
		try {
			this.formatter = new OutputFormatter(format);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			//TODO poslat do logu
		}
	}
	
	/**
	 * prezre pouzite referencie, vyziada z outputformatovaca naformatovane a zapise
	 */
	public void writetoFile(){
		String fileString = "";
		for (Entry<String, Data> entry : usedRefs.entrySet()){
			//fileString += "\\bibitem{" + entry.getKey() + "}" + System.getProperty("line.separator");
			fileString += formatter.getformattedref(entry.getKey(), entry.getValue());
		}
		try{
		  bufferedWriter = new BufferedWriter(new FileWriter(texOutuput));
		  bufferedWriter.write(fileString);
		  bufferedWriter.flush();
		  bufferedWriter.close();
		} catch(IOException e){
			//TODO poslat do logu
		}
	}
	
	/**
	 * zapise do BiBTexu
	 */
	public void saveAsBib(){
		try {
			BiBLoader bibTex = new BiBLoader(bibTexOutput);
			for (Entry<String, Data> ref : usedRefs.entrySet()){
				bibTex.addRef(ref.getValue().getType(), ref);
			}
			TreeMap<String, Data> library = new TreeMap<String, Data>(String.CASE_INSENSITIVE_ORDER);
			library.putAll(bibTex.getLibrary());
			bufferedWriter = new BufferedWriter(new FileWriter(bibTexOutput));
			for (Entry<String, Data> ref : library.entrySet()){
				bufferedWriter.write(buildBibTexString(ref));
			}
			bufferedWriter.flush();
			bufferedWriter.close();
			
		} catch (FileNotFoundException e) {
			// TODO do logu inac
			e.printStackTrace();
		} catch (IOException e) {
			// TODO do logu inac
			e.printStackTrace();
		}
	}
	
	/**
	 * vytvori cely bibtex string z vstupnych dat
	 * @param ref - entry referencie meno - data
	 * @return - naformatovane do bibtex podoby
	 */
	public String buildBibTexString(Entry<String, Data> ref){
		String res = "";
		res += '@' + ref.getValue().getType();
		res += "{" + ref.getKey() + "," + lineBreak;
		for (Entry<String, String> entry : ref.getValue().getValues().entrySet()){
			res += "  " + entry.getKey() + "={" + entry.getValue() + "}," + lineBreak;
		}
		res += "}" + lineBreak + lineBreak;
		return res;
	}
}
